#include <stdlib.h>
#include <utypes.h>
#include "menu.h"
#include "window.h"
#include "input.h"
#include "global.h"
#include <video-graphics.h>
#include <codepage.h>
#include "sound.h"

/** Estado do menu */
struct MenuState {
	Menu *menu; /**< Menu */
	Bool exit; /**< Indica se saímos do menu */
	Bool escaped; /**< Indica se saímos do menu sem selecionar nada */
	unsigned int sel; /**< Entrada no menu selecionada */
	int x; /**< Posição X do menu no ecrã */
	int y; /**< Posição Y do menu no ecrã */
};

/** Quantos menus estão abertos no momento */
static int num_menu = 0;

/** Lê dados do teclado */
static Bool menu_keyboard_cb (unsigned char scan_code, void *data)
{
	struct MenuState *st = data;

	if (scan_code == SC_UP) {
		if (st->sel == 0) {
			st->sel = st->menu->size - 1;
		} else {
			st->sel--;
		}

	} else if (scan_code == SC_DOWN) {
		if (st->sel >= st->menu->size - 1) {
			st->sel = 0;
		} else {
			st->sel++;
		}

	} else if (scan_code == SC_ENTER) {
		st->exit = true;
		st->escaped = false;

	} else if (scan_code == SC_ESC) {
		st->exit = true;
		st->escaped = true;
	}

	// Não permite que outras funções leiam do teclado
	return true;
}

/* Função de desenho do menu */
static void menu_show_cb (Window win, int x, int y, int w, int h, void *data)
{
	struct MenuState *st = data;
	
	// Obtém o título
	XPM xpm = xpm_get (st->menu->title);

	// Tamanho do menu
	int mw = (xpm->width > st->menu->w ? xpm->width : st->menu->w);
	int mh = 4 * st->menu->border + xpm->height + st->menu->size * (4+CHR_H);

	// Preenche a janela com a cor de fundo
	window_draw_rect (win, st->x, st->y, mw + 2*st->menu->border, mh, st->menu->bg);

	// Desenha o título
	xpm_draw (win, xpm, st->x + st->menu->border, st->y + st->menu->border);

	// Desenha as entradas
	int i;
	for (i = 0; i < st->menu->size; i++) {
		char fg = (i == st->sel ? st->menu->sel_fg : st->menu->unsel_fg);
		char bg = (i == st->sel ? st->menu->sel_bg : st->menu->unsel_bg);

		int ex = st->x + st->menu->border;
		int ey = st->y + i * (4+CHR_H + 1) + xpm->height + 2*st->menu->border;

		window_draw_rect (win, ex, ey, mw, 4+CHR_H, bg);
		window_draw_string (win, st->menu->entries[i].text, ex+2, ey+2, fg);
	}

}

/* Exibe o menu */
void menu_show (Menu *menu, int x, int y)
{
	struct MenuState m_st = {menu, false, false, 0, x, y}; // Estado do menu
	unsigned int msecs = MSECS;

	num_menu++;

	// Obtém as coordenadas do sistema de janelas
	int sx, sy;
	winsys_get_coord (&sx, &sy);
	
	// Cria a janela
	Window win = window_new (sx, sy, HRES, VRES, &m_st);
	window_show (win, menu_show_cb);
	window_set_plane (win, PLANE_MENU + num_menu);
	
	void *kbid = input_keyboard_register (menu_keyboard_cb, &m_st, true);

	while (!m_st.exit) {
		// Lê os dados do teclado
		input_keyboard_read ();
		// Mostra as janelas
		winsys_draw ();
		// Espera 20 milisegundos e toca música ao mesmo tempo
		sound_milisleep(20);
	}

	// Restaura as mudanças
	input_keyboard_unregister (kbid);
	window_delete (win);
	num_menu--;
	
	if (num_menu == 0) {
		sound_set_msecs (msecs);
	}

	// Chama a callback
	if (!m_st.escaped) {
		menu->entries[m_st.sel].cb (menu->data, menu->entries[m_st.sel].data);
	}
	
}


